module clock_divider (
    input clk,
    input rst_n,
    input[15:0] div1,
    input[15:0] div2,
    input[15:0] div3,
    output  clk1,
    output  clk2,
    output  clk3
);

reg[16:0] cp1;
reg[16:0] cp2;
reg[16:0] cp3;
reg[16:0] cn1;
reg[16:0] cn2;
reg[16:0] cn3;
reg       clk1_rp;
reg       clk1_rn;
reg       clk2_rp;
reg       clk2_rn;
reg       clk3_rp;
reg       clk3_rn;
assign clk1 = clk1_rp ^~ clk1_rn;
assign clk2 = clk2_rp ^~ clk2_rn;
assign clk3 = clk3_rp ^~ clk3_rn;
wire[16:0] count1;
wire[16:0] count2;
wire[16:0] count3;
wire[15:0] max_div;
assign count1 = cp1 + cn1;
assign count2 = cp2 + cn2;
assign count3 = cp3 + cn3;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cp1 <= 0;
        clk1_rp <= 0;
    end else begin
        if (count1 == div1) begin
            clk1_rp <= ~clk1_rp;
            cp1 <= 0;            
        end else begin
            if (cp1 > 1 && cn1 == 0 ) begin
                cp1 <= 1;
            end else begin
                cp1 <= cp1 + 1;
            end
        end
    end
end   

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cp2 <= 0;
        clk2_rp <= 0;
    end else begin
        if (count2 == div2) begin
            clk2_rp <= ~clk2_rp;
            cp2 <= 0;            
        end else begin
            if (cp2 > 1 && cn2 == 0 ) begin
                cp2 <= 1;
            end else begin
                cp2 <= cp2 + 1;
            end
        end
    end
end 

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cp3 <= 0;
        clk3_rp <= 0;
    end else begin
        if (count3 == div3) begin
            clk3_rp <= ~clk3_rp;
            cp3 <= 0;            
        end else begin
            if (cp3 > 1 && cn3 == 0 ) begin
                cp3 <= 1;
            end else begin
                cp3 <= cp3 + 1;
            end
        end
    end
end 

always @(negedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cn1 <= 0;
        clk1_rn <= 0;
    end else begin
        if (count1 == div1) begin
            clk1_rn <= ~clk1_rn;
            cn1 <= 0;            
        end else begin
            if (cn1 > 1 && cp1 == 0 ) begin
                cn1 <= 1;
            end else begin
                cn1 <= cn1 + 1;
            end
        end
    end
end 

always @(negedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cn2 <= 0;
        clk2_rn <= 0;
    end else begin
        if (count2 == div2) begin
            clk2_rn <= ~clk2_rn;
            cn2 <= 0;            
        end else begin
            if (cn2 > 1 && cp2 == 0 ) begin
                cn2 <= 1;
            end else begin
                cn2 <= cn2 + 1;
            end
        end
    end
end
always @(negedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cn3 <= 0;
        clk3_rn <= 0;
    end else begin
        if (count3 == div3) begin
            clk3_rn <= ~clk3_rn;
            cn3 <= 0;            
        end else begin
            if (cn3 > 1 && cp3== 0 ) begin
                cn3 <= 1;
            end else begin
                cn3 <= cn3 + 1;
            end
        end
    end
end

endmodule